package com.nari.ies.server.utils;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @Date: 2022/9/22 18:59
 * @Description: com.niescloud.nw.service.util
 * @Version: 1.0
 */
public class DateUtil {

    /**
     * 小时数 "H"
     */
    public static SimpleDateFormat SDF_ONLY_H = new SimpleDateFormat("H");

    /**
     * 日期格式 "yyyy-MM-dd HH:mm:ss"
     */
    public static SimpleDateFormat SDF_SS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 小时级别 "yyyy-MM-dd hh24"
     */
    public static SimpleDateFormat SDF_HOUR = new SimpleDateFormat("yyyy-MM-dd hh24");

    /**
     * 日级别 "yyyy-MM-dd"
     */
    public static SimpleDateFormat SDF_DAY = new SimpleDateFormat("yyyy-MM-dd");

    /**
     * 年级别 "yyyy"
     */
    public static SimpleDateFormat SDF_YEAR = new SimpleDateFormat("yyyy");

    /**
     * 月级别 "yyyy-MM"
     */
    public static SimpleDateFormat SDF_MONTH = new SimpleDateFormat("yyyy-MM");

    public static SimpleDateFormat SDF_MI = new SimpleDateFormat("HHmm");

    /**
     * 获取昨天的初始时间
     *
     * @return
     */
    public static Date getYesterday() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getToday());
        cal.add(Calendar.DATE, -1);
        return cal.getTime();
    }

    /**
     * 获取给定日期的下一天
     *
     * @param startDate
     * @return
     */
    public static Date getNextDay(Date startDate) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(startDate);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.add(Calendar.DATE, 1);
        return cal.getTime();
    }

    /**
     * 获取今天的初始时间
     *
     * @return
     */
    public static Date getToday() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取指定日期的初始时间
     *
     * @return
     */
    public static Date getInitDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取每年第一天
     *
     * @return
     */
    public static Date getFirstDateOfYear(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.MONTH, 0);
        cal.set(Calendar.DATE, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取每月第一天
     *
     * @return
     */
    public static Date getFirstDateOfMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DATE, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取每周第一天
     *
     * @return
     */
    public static Date getFirstDateOfWeek(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return cal.getTime();
    }


    /**
     * 获取每天的凌晨时间点
     *
     * @return
     */
    public static Date getZeroTimeOfDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return cal.getTime();
    }

    /**
     * 设定传入时间的小时数, 如果传入24则是获取明日凌晨
     *
     * @return
     */
    public static Date getDate(Date date, int hour) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, hour);
        return cal.getTime();
    }



    public static Date getDate(String time) {
        return new Date(time.replace('-', '/'));
    }

    /**
     * 获取指n分钟后的日期
     *
     * @param date
     * @return
     */
    public static Date addMinsDate(Date date, int n) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MINUTE, n);
        return cal.getTime();
    }

    /**
     * 获取指n小时后的日期
     *
     * @param date 日期
     * @return Date
     */
    public static Date addHourDate(Date date, int n) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.HOUR_OF_DAY, n);
        return cal.getTime();
    }

    /**
     * 获取Date的分钟值
     *
     * @param date
     * @return
     */
    public static int getMinOfDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.MINUTE);
    }

    /**
     * 检查Date是否是当天
     *
     * @param date
     * @return
     */
    public static boolean checkTody(Date date) {
        int nYear = date.getYear();
        int nMonth = date.getMonth();
        int nDay = date.getDate();

        Date now = new Date();

        int nYear1 = now.getYear();
        int nMonth1 = now.getMonth();
        int nDay1 = now.getDate();

        return nYear == nYear1 && nMonth == nMonth1 && nDay == nDay1;
    }

    /**
     * 检查日期是否当月
     *
     * @param date
     * @return
     */
    public static boolean checkThisMonth(Date date) {
        int nYear = date.getYear();
        int nMonth = date.getMonth();

        Date now = new Date();

        int nYear1 = now.getYear();
        int nMonth1 = now.getMonth();

        return nYear == nYear1 && nMonth == nMonth1;
    }

    /**
     * 检查日期是否当年
     *
     * @param date
     * @return
     */
    public static boolean checkThisYear(Date date) {
        int nYear = date.getYear();

        Date now = new Date();

        int nYear1 = now.getYear();

        return nYear == nYear1;
    }

    /**
     * 获取指定的时间
     *
     * @return
     */
    public static Date getDate(int year, int month, int date, int hour, int mi, int sec) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DATE, date);
        cal.set(Calendar.HOUR_OF_DAY, hour);
        cal.set(Calendar.MINUTE, mi);
        cal.set(Calendar.SECOND, sec);
        return cal.getTime();
    }

    public static int getYearFromDate(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = sdf.format(date);
        String year = time.substring(0, 4);
        return Integer.parseInt(year);
    }

    /**
     * 获取当前日期是一周的第几天
     *
     * @return
     */
    public static int getWeekOfDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.DAY_OF_WEEK);
    }


    /**
     * 获取当前周已过去的天
     *
     * @return
     */
    public static List<Object> getWeekdaysOfDate() {
        String strWeek[] = {"周一", "周二", "周三", "周四", "周五", "周六", "周日"};
        List<Object> weekDays = new ArrayList<Object>();
        for (int i = 0; i < strWeek.length; ++i) {
            weekDays.add(strWeek[i]);
        }

        return weekDays;
    }

    /**
     * 获得今年当前月份以及之前的月份
     *
     * @return
     */
    public static List<Object> getMonthsOfDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int month = cal.get(Calendar.MONTH);
        List<Object> monthList = new ArrayList<Object>();
        for (int i = 1; i <= month + 1; ++i) {
            monthList.add(i + "月");
        }
        return monthList;
    }

    /**
     * 获得今年 至n年前的年份
     *
     * @return
     */
    public static List<Object> getYearsOfDate(Date date, int n) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int year = cal.get(Calendar.YEAR);
        List<Object> yearList = new ArrayList<Object>();
        for (int i = n; i >= 0; --i) {
            int tmp = year - i;
            yearList.add(tmp + "年");
        }
        return yearList;
    }

    /**
     * 获得date整点的时间
     *
     * @return
     */
    public static Date getClockOfDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取指定日期的前几天
     *
     * @param date
     * @param day
     * @return
     * @throws ParseException
     */
    public static Date getBeforeDate(Date date, int day) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DATE, -day);

        return c.getTime();
    }

    /**
     * 获取指定日期的后几天
     *
     * @param date
     * @param day
     * @return
     * @throws ParseException
     */
    public static Date getAfterDate(Date date, int day) {

        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DATE, day);

        return c.getTime();
    }

    /**
     * 毫秒转日期字符串
     *
     * @param milliseconds
     * @return
     */
    public static String Millisecond2Date(Long milliseconds) {

        Date date = new Date();
        date.setTime(milliseconds);
        return SDF_SS.format(date);
    }

    /**
     * 获取当前月份的初始日期
     *
     * @return
     */
    public static Date getStartMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        return cal.getTime();
    }

    /**
     * 获取当前月份的末尾日期
     *
     * @return
     */
    public static Date getEndMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, 1);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.add(Calendar.DAY_OF_MONTH, -1);
        return cal.getTime();
    }

    /**
     * 获取当前日期的年末最后一天日期
     *
     * @return
     */
    public static Date getEndYear(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_YEAR, 1);
        cal.add(Calendar.YEAR, 1);
        cal.add(Calendar.DAY_OF_YEAR, -1);
        return cal.getTime();
    }

    /**
     * 根据小时和分，获取当天对应的时间
     *
     * @return
     */
    public static Date getDateOfHourAndMinute(String hour, String minute) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, Integer.valueOf(hour));
        cal.set(Calendar.MINUTE, Integer.valueOf(minute));

        return cal.getTime();
    }

    /**
     * 获取下个步长整分钟的点位，
     * 比如当前时间为11点20分，会得到11点30分
     *
     * @param date
     * @return
     */
    public static Date getNext15Minute(Date date,int step) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        int minute = cal.get(Calendar.MINUTE);
        while (minute % step != 0) {
            minute++;
            if (minute == 0) {
                hour++;
                minute = 0;
            }
        }

        cal.set(Calendar.HOUR_OF_DAY, hour);
        cal.set(Calendar.MINUTE, minute);
        cal.set(Calendar.SECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取上个步长整分钟的点位，
     * 比如当前时间为11点20分，会得到11点15分
     *
     * @param date
     * @return
     */
    public static Date getPreviousMinute(Date date,int step) {
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.set(Calendar.MINUTE,(c.get(Calendar.MINUTE))/step * step);
        c.set(Calendar.SECOND,0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }


    /**
     * 获取两日期之间的天数
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDays(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1 = cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);

        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        if (year1 != year2) {
            //不同一年
            int timeDistance = 0;
            for (int i = year1; i < year2; i++) {
                if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) {
                    //闰年
                    timeDistance += 366;
                } else {
                    //不是闰年
                    timeDistance += 365;
                }
            }

            return timeDistance + (day2 - day1);
        } else {
            // 不同年
            return day2 - day1;
        }
    }

    /**
     * 获取指定日期的周数
     *
     * @return
     */
    public static int getWeek(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.DAY_OF_WEEK);
    }

    /**
     * 给定日期，分钟数，根据正负取日期的前几分钟或者后几分钟
     * @param date
     * @param minute
     * @return
     */
    public static Date getBeforeOrAfterMinute(Date date ,int minute) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE, minute);
        return c.getTime();
    }

    /**
     * 获取给定时间最接近的整步长时间的点位
     * @param date 给定时间
     * @param step 步长
     * @param type start:往后，end:往前
     * @return
     */
    public static String getColumnName(Date date,String type,int step){
        Calendar c = Calendar.getInstance();
        if ("start".equals(type)){
            c.setTime(date);
            int hour = c.get(Calendar.HOUR_OF_DAY);
            int minute = c.get(Calendar.MINUTE);
            while (minute % step != 0) {
                minute++;
                if (minute == 0) {
                    hour++;
                }
            }
            c.set(Calendar.HOUR_OF_DAY, hour);
            c.set(Calendar.MINUTE, minute);
            c.set(Calendar.SECOND, 0);
        } else {
            c.setTime(date);
            c.set(Calendar.MINUTE,(c.get(Calendar.MINUTE))/step * step);
            c.set(Calendar.SECOND,0);
            c.set(Calendar.MILLISECOND, 0);
        }
        return "V"+SDF_MI.format(c.getTime());
    }
}
